/*
 * Created on May 31, 2005 
 */
package com.erclab.internal.xpresso;

import java.util.*;

import org.apache.log4j.Logger;

import com.erclab.internal.xpresso.exceptions.*;
import com.erclab.internal.xpresso.lang.LanguageHandler;
import com.erclab.internal.xpresso.repositories.Repository;
import com.erclab.internal.xpresso.security.AccessController;
import com.erclab.internal.xpresso.security.UserDirectory;
import com.erclab.internal.xpresso.util.ObjectCreator;
import com.erclab.internal.xpresso.cache.CacheManager;
import com.erclab.internal.xpresso.cache.CacheSingleton;
import com.erclab.internal.xpresso.conf.Settings;

/**
 * @author Enrique Rodriguez.
 *
 */
public class Application {

	// Create the log for this class
	private static final Logger log = Logger.getLogger(Application.class);
	
	private PropertyResourceBundle properties;
	private String applicationName;
	private String applicationDescription;

	private void createRepository() throws ApplicationException {
		String directoryClassName = properties.getString("repository.directory.class");
		String securityClassName = properties.getString("repository.security.class");
		String languageClassName = properties.getString("application.language.handler");
		String objectCreatorClassName = properties.getString("application.objectCreator.class");
		String cacheManagerClassName = properties.getString("application.cacheManager.class");
		
		// Information about the repositories
		String repositoryClassName = properties.getString("application.repository.class");		
	
		if(repositoryClassName == null)
			throw new ApplicationException("The property application.respository.class is not correctly set");

		try {
			// Set all properties
			Settings.setProperties(properties);
			
			// Create Application Repository class
			Class repositoryClass = Class.forName(repositoryClassName);
			Repository repository = (Repository) repositoryClass.newInstance();
			repository.setup();
			Settings.setRepository(repository);
			
			// Create directory class
			Class directoryClass = Class.forName(directoryClassName);
			UserDirectory directory = (UserDirectory) directoryClass.newInstance();
			Settings.setUserDirectory(directory);
			Settings.setDirectoryIdDataSource(Integer.parseInt(properties.getString("repository.directory.iddatasource")));
			
			// Create security class
			Class securityClass = Class.forName(securityClassName);
			AccessController security = (AccessController) securityClass.newInstance();
			Settings.setAccessController(security);
			
			// Create Language Handler
			Class languageClass = Class.forName(languageClassName);
			Settings.setLanguageHandler((LanguageHandler) languageClass.newInstance());

			// Create object creator
			Class objectCreatorClass = Class.forName(objectCreatorClassName);
			Settings.setObjectCreator((ObjectCreator) objectCreatorClass.newInstance());			
			
			// Create cache manager
			Class cacheManagerClass = Class.forName(cacheManagerClassName);
			Settings.setCacheManager((CacheManager) cacheManagerClass.newInstance());
			
			// Admin mode
			Settings.setAdminMode(properties.getString("application.adminMode"));
			
		}catch(ClassNotFoundException e){
			log.fatal(e);
			throw new ApplicationException("One of the classes defined in the application.properties file could not be found: " + e);
		}catch(Exception e){
			log.fatal(e);
			throw new ApplicationException("A problem ocurred while creating the repository class: " + e);
		}

	}
	
	private void loadApplicationProperties(){
		log.info("Loading xpresso properties ....");
		properties = (PropertyResourceBundle)ResourceBundle.getBundle("com.erclab.internal.xpresso.application");
		log.info("Properties loaded");
		applicationName = properties.getString("application.name");
		log.info("Application name: " + applicationName);
		applicationDescription = properties.getString("application.description");
		log.info("Application description: " + applicationDescription);
	}

	public Application() throws ApplicationException {
		log.info("STARTING xpresso framework .... ");
		loadApplicationProperties();
		try {
			createRepository();
		} catch (ApplicationException e){
			log.fatal("The application repository could not be created: " + e);
			throw e;
		}
		log.info("Initializing the cache ...");
		CacheSingleton.getCache();
	}
	
	/**
	 * @return
	 */
	public String getApplicationDescription() {
		return applicationDescription;
	}

	/**
	 * @return
	 */
	public String getApplicationName() {
		return applicationName;
	}

}
